Object-oriented Programming
Object-Oriented Programming (OOP) is a programming paradigm that uses "objects" to design software. It allows developers to create classes that encapsulate data and functions, promoting code reusability and modularity.
Key Concepts
- Classes and Objects: A class is a blueprint for creating objects (instances), providing initial values for state (attributes) and implementations of behavior (methods).
- Attributes: Variables that belong to an instance or class.
- Methods: Functions defined within a class that describe the behaviors of an object.
What Is a Method?
Methods are functions associated with object parameters that modify the state of that object. They are essential for defining the behaviors of an object and can be categorized into:
Instance Methods
Instance methods are the most common type of methods in Python:
- Defined within a class and operate on instances of that class.
- The first parameter is always
self
, representing the instance. - Can access and modify instance attributes.
class Apple:
def __init__(self, color, flavor):
self.color = color
self.flavor = flavor
def description(self):
return f"This apple is {self.color} and tastes {self.flavor}."
Usage:
jonagold = Apple("red", "sweet")
print(jonagold.description())
# Output: This apple is red and tastes sweet.
Class Methods
Class methods are called on the class itself, not on instances:
- Use the
@classmethod
decorator. - The first parameter is
cls
, representing the class. - Commonly used for factory methods or to modify class state.
class Fruit:
count = 0
@classmethod
def increase_count(cls):
cls.count += 1
Static Methods
Static methods are utility functions within a class:
- Use the
@staticmethod
decorator. - Do not take
self
orcls
as a parameter. - Behave like regular functions but reside within the class's namespace.
class MathUtils:
@staticmethod
def add(a, b):
return a + b
Choosing a Method Type
- Instance Methods: When you need to access or modify instance-specific data.
- Class Methods: When you need to access or modify class-level data.
- Static Methods: When you need a utility function that doesn't access instance or class data.
Constructors and Special Methods
The Constructor: __init__
The constructor method __init__
initializes an object's attributes upon creation:
class Apple:
def __init__(self, color="red", flavor="sweet"):
self.color = color
self.flavor = flavor
Usage:
honeycrisp = Apple("green", "tart")
print(honeycrisp.color)
# Output: green
Other Special Methods
Special methods in Python start and end with double underscores (__
), known as dunder methods. They allow objects to interact with Python's built-in functions and operators.
Common Dunder Methods
-
__str__(self)
: Defines the string representation of the object forprint()
andstr()
.class Apple:
def __str__(self):
return f"This apple is {self.color} and tastes {self.flavor}."Usage:
print(honeycrisp)
# Output: This apple is green and tastes tart. -
__len__(self)
: Returns the length of the object. -
__eq__(self, other)
: Defines equality comparison between two objects.
Example: Custom String Representation
class Piglet:
def __init__(self, name="Piglet"):
self.name = name
def __str__(self):
return f"Oink! I'm {self.name}!"
hamlet = Piglet("Hamlet")
print(hamlet)
# Output: Oink! I'm Hamlet!
Special Methods as Operators
Python allows you to define or override the behavior of operators using special methods.
Overriding Operators
- Arithmetic Operators:
__add__
,__sub__
,__mul__
,__truediv__
, etc. - Comparison Operators:
__eq__
,__lt__
,__gt__
, etc.
Example: Overriding the Addition Operator
class Triangle:
def __init__(self, base, height):
self.base = base
self.height = height
def area(self):
return 0.5 * self.base * self.height
def __add__(self, other):
return self.area() + other.area()
triangle1 = Triangle(10, 5)
triangle2 = Triangle(6, 8)
print(f"Triangle 1 area: {triangle1.area()}")
print(f"Triangle 2 area: {triangle2.area()}")
print(f"Combined area: {triangle1 + triangle2}")
# Output:
# Triangle 1 area: 25.0
# Triangle 2 area: 24.0
# Combined area: 49.0
For a full list of operator methods, refer to Python's operator module.
Instance Methods in Depth
Instance methods are crucial for defining the behaviors of objects.
Defining and Using Instance Methods
class Piglet:
name = "Piglet"
def speak(self):
print(f"Oink! I'm {self.name}!")
def pig_years(self):
return self.age * 18
hamlet = Piglet()
hamlet.name = "Hamlet"
hamlet.age = 2
hamlet.speak()
# Output: Oink! I'm Hamlet!
print(hamlet.pig_years())
# Output: 36
- Instance Variables: Variables unique to each instance.
- Methods: Can perform actions and return values.
Key Takeaways
- Encapsulation: Classes encapsulate data and behaviors.
- Reusability: Promotes code reuse and organization.
- Flexibility: Special methods allow customization of object interactions.